<template>
    <div class="claer" ref="clear">
    </div>
    <div class="mb-4">
        <el-button type="primary" @Click="startAnimation">开始动画</el-button>
    </div>
</template>

<script setup lang="ts">
import * as THREE from "three";
import { onMounted, ref } from "vue";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import * as TWEEN from "three/examples/jsm/libs/tween.module.js";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { motionTrajectory } from "../utils/data.ts";


let clear = ref();
// 创建场景
const scene = new (THREE as any).Scene();
scene.background = new (THREE as any).Color(0xffffff);

//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);


// 创建渲染器
const render = new THREE.WebGLRenderer({ antialias: true });
render.setSize(800, 500);
render.setPixelRatio(window.devicePixelRatio);
render.setClearColor(0xffffff, 1);

// 创建相机
const camera = new (THREE as any).PerspectiveCamera(45, 800 / 500, 0.1, 1000);
const bestLength = 80;
//  相机位置
camera.position.x = -3.871794008045925;
camera.position.y = 5.545051524721194;
camera.position.z = 11.183973463819818;
camera.lookAt(0, 0, 0);

// 轨道滑动器
const controls = new OrbitControls(camera, render.domElement); //轨道滑动器
controls.enableDamping = true;  // 设置带阻尼的惯性
controls.dampingFactor = 0.1; // 设置阻尼系数
controls.rotateSpeed = 0.14; // 旋转速度

// 创建灯光
const createLight = (x: number, y: number, z: number) => {
    const color = 0xffffff; //  灯光颜色
    const intensity = 1; // 灯光强度
    const light = new (THREE as any).DirectionalLight(color, intensity);
    light.position.set(x, y, z);
    light.target.position.set(0, 0, 0);
    return light;
};
const lights = [
    createLight(bestLength, bestLength, -bestLength),
    createLight(-bestLength, bestLength, -bestLength),
    createLight(-bestLength, bestLength, bestLength),
    createLight(-bestLength, -bestLength, bestLength),
    createLight(bestLength, -bestLength, -bestLength),
    createLight(-bestLength, -bestLength, -bestLength),
    createLight(-bestLength, -bestLength, bestLength),
    createLight(bestLength, -bestLength, bestLength),
];
lights.forEach((light) => scene.add(light));
lights.forEach((light) => scene.add(light.target));

//  渲染函数
const animate = () => {
    controls.update(); // 轨道滑动器更新
    requestAnimationFrame(animate); // 递归调用
    render.render(scene, camera); // 渲染
    (TWEEN as any).update(); // 更新动画
    // 打印相机位置
    // console.log(`相机位置 - X: ${camera.position.x}, Y: ${camera.position.y}, Z: ${camera.position.z}`);
};

//模型元素
let model = ref({
    body: new THREE.Object3D(),
    left: new THREE.Object3D(),
    car_bottom: new THREE.Object3D(),
    car_top: new THREE.Object3D(),
    leftTween: new TWEEN.Tween({}),
    car_bottomTween: new TWEEN.Tween({}),
    car_topTween: new TWEEN.Tween({}),
});

// 加载模型
const gltfLoader = new GLTFLoader();
// gltfLoader.load('/public/model/body.glb',
//     (gltf) => {
//         model.value.body = gltf.scene
//         // gltf.scene.scale.set(0.15, 0.15, 0.15)
//         gltf.scene.position.y = 1.389;
//         gltf.scene.position.z = -2;
//         scene.add(gltf.scene);
//     }
// );
// gltfLoader.load('/public/model/car_bottom.glb',
//     (gltf) => {
//         const sceneObj = gltf.scene.children[0];
//         model.value.car_bottom = sceneObj;
//         model.value.car_bottomTween = new TWEEN.Tween(gltf.scene.position);
//         model.value.car_bottom.position.y = 0.625;
//         scene.add(sceneObj);
//     }
// );
// gltfLoader.load('/public/model/car_top.glb',
//     (gltf) => {
//         const sceneObj = gltf.scene.children[0];
//         model.value.car_top = sceneObj;
//         model.value.car_topTween = new TWEEN.Tween(gltf.scene.position);
//         scene.add(sceneObj);
//     }
// );
// gltfLoader.load('/public/model/left.glb',
//     (gltf) => {
//         const sceneObj = gltf.scene.children[0];
//         sceneObj.position.set(-3.147, 1.683, 22.155);
//         model.value.left = sceneObj;
//         console.log("3d", model.value.left);
//         model.value.leftTween = new TWEEN.Tween(gltf.scene.rotation)
//         scene.add(sceneObj);
//     }
// );
// gltfLoader.load('/public/model/left.glb',
//     (gltf) => {
//         model.value.left.rotation = gltf.scene.rotation;
//         console.log(model.value.left);
//         gltf.scene.position.x = -3.147;
//         gltf.scene.position.y = 1.383;
//         gltf.scene.position.z = 22.155;
//         model.value.leftTween = new TWEEN.Tween(gltf.scene.rotation);
//         console.log(model.value.leftTween);
//         scene.add(gltf.scene);
//     }
// );


// 加载模型
gltfLoader.load('/public/model/body.glb', function (gltf) {
  addGltf(gltf, () => {
    model.value.body = gltf.scene
    gltf.scene.scale.set(0.15, 0.15, 0.15)
    gltf.scene.position.y = 1.389;
    gltf.scene.position.z = -2;
    scene.add(gltf.scene)
  })
  gltfLoader.load('/public/model/car_bottom.glb', function (gltf) {
    addGltf(gltf, () => {
      model.value.car_bottom = gltf.scene
      model.value.car_bottomTween = new TWEEN.Tween(gltf.scene.position)
      model.value.car_bottom.position.y = 0.625;
      model.value.body.add(gltf.scene);
    })
    gltfLoader.load('/public/model/car_top.glb', function (gltf) {
      addGltf(gltf, () => {
        model.value.car_top = gltf.scene
        model.value.car_topTween = new TWEEN.Tween(gltf.scene.position)
        model.value.car_bottom.add(gltf.scene);
      })
    })
  })
  gltfLoader.load('/public/model/left.glb', function (gltf) {
    addGltf(gltf, () => {
      model.value.left = gltf.scene
      gltf.scene.position.x = -3.147;
      gltf.scene.position.y = 1.783;
      gltf.scene.position.z = 22.055
      model.value.leftTween = new TWEEN.Tween(gltf.scene.rotation)
      model.value.body.add(gltf.scene);
    })
  })
})
// 添加模型方法
const addGltf = (gltf : any, callback : any) => {
  callback(gltf.scene)
}


const PI = Math.PI;
const startLeftTween = (value: number) => {
    console.log("开始旋转动画");
    model.value.leftTween.stop();
    model.value.leftTween.to({ x: (value * PI * 10) }, (value + 2) * 1000).start();
    model.value.leftTween = new TWEEN.Tween(model.value.left.rotation);
};

const startBottomTween = (value: number) => {
    // console.log("model.value.leftTween", model.value.car_bottom);
    console.log("底座开始移动动画");
    model.value.car_bottomTween.stop();
    model.value.car_bottomTween.to({ x: value }, 1000).start();
    model.value.car_bottomTween = new TWEEN.Tween(model.value.car_bottom.position);
};

const startTopTween = (value: number) => {
    // console.log("Top开始移动动画");
    model.value.car_topTween.stop();
    model.value.car_topTween.to({ z: value }, 1000).start();
    model.value.car_topTween = new TWEEN.Tween(model.value.car_top.position);
};

let animationInterval: number | null = null;
// 开始动画
const startAnimation = () => {
    let index = 0;
    startLeftTween(motionTrajectory.length);
    animationInterval = setInterval(() => {
        index++;
        if (index >= motionTrajectory.length) {
            endAnimation();
            index = 0;
        } else {
            startBottomTween(motionTrajectory[index].x);
            startTopTween(motionTrajectory[index].z);
        }
    }, 1000);
};
// 结束动画
const endAnimation = () => {
    if (animationInterval !== null) {
        clearInterval(animationInterval);
        animationInterval = null;
    }
    model.value.leftTween.stop();
    startTopTween(0);
    startBottomTween(0);
};

// 挂载
onMounted(() => {
    clear.value.appendChild(render.domElement);
    animate();
});
</script>

<style lang="less">
.claer {
    width: 800px;
    height: 500px;
    border: 1px solid #ccc;
}
</style>